<?php


namespace IDock\Insurance\LIHI;

use Exception;
use IDock\Http\Response;
use IDock\IDock\IDockInterface;
use IDock\Insurance\LIHI\Request\EPolicyDownloadRequest;
use IDock\Insurance\LIHI\Request\LIHITokenRequest;
use IDock\Insurance\LIHI\Request\NonCarInquiryRequest;
use IDock\Insurance\LIHI\Request\NonCarProductListRequest;
use IDock\Insurance\LIHI\Request\PolicyPaymentRequest;
use IDock\Insurance\LIHI\Request\PremiumInquiryRequest;
use IDock\Insurance\LIHI\Request\ProposalRecallRequest;
use IDock\Insurance\LIHI\Request\ProposalStatusRequest;
use IDock\Insurance\LIHI\Request\RenewalInquiryRequest;
use IDock\Insurance\LIHI\Request\UnderwritingRequest;
use IDock\Insurance\LIHI\Request\UploadFileRequest;
use IDock\Insurance\LIHI\Request\ValidateCarRequest;
use IDock\Insurance\LIHI\Request\VehicleActualValueRequest;
use IDock\Insurance\LIHI\Request\VehicleConfirmRequest;
use IDock\Insurance\LIHI\Request\VehicleModelRequest;
use IDock\Insurance\LIHI\Response\CommonResponse;
use IDock\Insurance\LIHI\Response\EPolicyDownloadResponse;
use IDock\Insurance\LIHI\Response\NonCarInquiryResponse;
use IDock\Insurance\LIHI\Response\NonCarProductListResponse;
use IDock\Insurance\LIHI\Response\PolicyPaymentResponse;
use IDock\Insurance\LIHI\Response\PremiumInquiryResponse;
use IDock\Insurance\LIHI\Response\ProposalRecallResponse;
use IDock\Insurance\LIHI\Response\ProposalStatusResponse;
use IDock\Insurance\LIHI\Response\RenewalInquiryResponse;
use IDock\Insurance\LIHI\Response\UnderwritingResponse;
use IDock\Insurance\LIHI\Response\ValidateCarResponse;
use IDock\Insurance\LIHI\Response\VehicleActualValueResponse;
use IDock\Insurance\LIHI\Response\VehicleModelResponse;
use IDock\Printer\NonCar\NonCarInquiryPrinter;
use IDock\Printer\NonCar\NonCarInquirySinglePrinter;
use IDock\Visitor\EPolicyDownloadVisitor;
use IDock\Visitor\NonCar\NonCarInquiryVisitor;
use IDock\Visitor\NonCar\NonCarProductListVisitor;
use IDock\Visitor\NonCar\NonCarProductVisitor;
use IDock\Visitor\PolicyInfoVisitor;
use IDock\Visitor\PolicyPaymentVisitor;
use IDock\Visitor\Premium\PremiumInquiryVisitor;
use IDock\Visitor\ProposalRecallVisitor;
use IDock\Visitor\ProposalStatusVisitor;
use IDock\Visitor\RenewalInquiryVisitor;
use IDock\Visitor\UnderwritingRecallVisitor;
use IDock\Visitor\UploadFileVisitor;
use IDock\Visitor\ValidateCarVisitor;
use IDock\Visitor\VehicleActualValueVisitor;
use IDock\Visitor\VehicleModelVisitor;

class LIHIConstruct extends Builder implements IDockInterface
{
    public $config = [];

    public function __construct($config)
    {
        $this->config = $config;

        $this->partnerAccountCode = $config['partnerAccountCode'] ?? '';

        //$this->recordCode = $config['recordCode'] ?? '';
        //$this->agreementNo = $config['agreementNo'] ?? '';
        $this->tokenUrl = $config['tokenUrl'] ?? '';
        $this->notifyUrl = $config['notifyUrl'] ?? '';
    }

    /**
     * 续保查询
     * @param RenewalInquiryVisitor $renewalInquiryVisitor
     * @return RenewalInquiryResponse
     */
    public function renewalInquiry(RenewalInquiryVisitor $renewalInquiryVisitor): RenewalInquiryResponse
    {

        $request = new RenewalInquiryRequest();
        $request->setVisitor($renewalInquiryVisitor);
        /*** @var RenewalInquiryResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 车型查询
     * @param VehicleModelVisitor $vehicleModelVisitor
     * @return VehicleModelResponse
     */
    public function vehicleModel(VehicleModelVisitor $vehicleModelVisitor): VehicleModelResponse
    {
        $request = new VehicleModelRequest();

        $request->setVisitor($vehicleModelVisitor);

        /*** @var VehicleModelResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 车辆实际价格
     */
    public function vehicleActualValue(VehicleActualValueVisitor $vehicleActualValueVisitor): Response
    {
        $request = new VehicleActualValueRequest();
        $request->setVisitor($vehicleActualValueVisitor);

        /*** @var VehicleActualValueResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 询价前置
     */
    public function preInquiry(PremiumInquiryVisitor $premiumInquiryVisitor): Response
    {
        return new Response(200);
    }

    public function validateCar(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
    }

    /**
     * 询价
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return Response|PremiumInquiryResponse
     * @throws Exception
     */
    public function premiumInquiry(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
        if ($premiumInquiryVisitor->vehiclePrinter) {
            //车型确认接口

            $vehicleConfirmRequest = new VehicleConfirmRequest();
            $vehicleConfirmRequest->setVisitor($premiumInquiryVisitor);
            $response = $this->execute($vehicleConfirmRequest);

        } else {
            //第一次算价
            $request = new PremiumInquiryRequest;
            $request->setVisitor($premiumInquiryVisitor);
            $response = $this->execute($request);
        }

        /*** @var PremiumInquiryResponse $response */
        if (!$response->isSuccess()) {
            return $response;
        }

        //续保类型
        $response->renewalFlagType($premiumInquiryVisitor->getVehicleVisitor()->licenseNo, $premiumInquiryVisitor->getVehicleVisitor()->firstRegisterDate);

        if (!empty($premiumInquiryVisitor->getNonCarInquiryVisitor()->getNonCarList()) && $response->getPrinter()->success) {
            $premiumInquiryVisitor->getExtInfoVisitor()->argc['proposalNo'] = $response->printer->biInquiryNo ?: $response->printer->ciInquiryNo;
            if (empty($response->printer->argc['flowId'])) {
                throw new Exception("获取flowId失败");
            }
            $premiumInquiryVisitor->getExtInfoVisitor()->argc['flowId'] = $response->printer->argc['flowId'];
            $this->noCarInquiry($premiumInquiryVisitor);
//            $response->printer->argc['hasNoCar'] = 1;
        }

        //非车
        $nonCarInquiryPrinter = new NonCarInquiryPrinter();
        $totalPremium = 0;
        foreach ($premiumInquiryVisitor->getNonCarInquiryVisitor()->getNonCarList() as $item) {
            /*** @var $item NonCarProductVisitor */
            $single = new NonCarInquirySinglePrinter();
            $single->premium = $item->premium;
            $single->planCode = $item->planCode;
            $single->productCode = $item->productCode;
            $single->statusCode = 'success';
            $totalPremium += $single->premium * $item->insuredNum;
            $nonCarInquiryPrinter->noCarInquirySingleAppend($single);
        }
        $nonCarInquiryPrinter->totalPremium = $totalPremium;

        $response->printer->nonCarInquiryPrinter = $nonCarInquiryPrinter;
        return $response;
    }

    public function noCarInquiry(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
        $request = new NonCarInquiryRequest();
        $request->setVisitor($premiumInquiryVisitor);

        $request->agreementCode = $this->agreementNo;

        $request->proposalNo = $premiumInquiryVisitor->getExtInfoVisitor()->argc['proposalNo'];
        /*** @var NonCarInquiryResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 核保
     * @param PremiumInquiryVisitor $premiumInquiryVisitor
     * @return Response
     */
    public function underwriting(PremiumInquiryVisitor $premiumInquiryVisitor): Response
    {
        if (!empty($premiumInquiryVisitor->getFileList())) {
            $fileArr = [];
            foreach ($premiumInquiryVisitor->getFileList() as $value) {
                if (in_array(LIHIEnums::$uploadFileType[$value['type']], ['200', '201', '204', '1005'])) {
                    $fileArr[LIHIEnums::$uploadFileType[$value['type']]][] = $value;
                } else {
                    $fileArr[][] = $value;
                }
            }
            foreach ($fileArr as $value) {
                $uploadFileVisitor = new UploadFileVisitor();
                $uploadFileVisitor->biInquiryNo = $premiumInquiryVisitor->getUnderwritingVisitor()->biInquiryNo;
                $uploadFileVisitor->ciInquiryNo = $premiumInquiryVisitor->getUnderwritingVisitor()->ciInquiryNo;
                if (count($value) == 1) {
                    $uploadFileVisitor->fileAppend($value[0]['type'], $value[0]['url']);
                    $uploadFileVisitor->argc = $premiumInquiryVisitor->getExtInfoVisitor()->argc;
                } elseif (count($value) > 1) {
                    $uploadFileVisitor->fileAppend($value[0]['type'], $value[0]['url']);
                    $uploadFileVisitor->fileAppend($value[1]['type'], $value[1]['url']);
                    $uploadFileVisitor->argc = $premiumInquiryVisitor->getExtInfoVisitor()->argc;
                }
                $request1 = new UploadFileRequest();
                $request1->setVisitor($uploadFileVisitor);
                $this->execute($request1);
            }
        }
        $request = new UnderwritingRequest();
        $request->setVisitor($premiumInquiryVisitor);

        //非车核保
        //$this->nonCarUnderwriting($premiumInquiryVisitor->getNonCarInquiryPrinter());

        /*** @var UnderwritingResponse $response */
        $underwritingResponse = $this->execute($request);
        if (!$underwritingResponse->isSuccess()) {
            if ($underwritingResponse->getError() == '提交核保失败！请使用OCR识别后再提核') {
                //查询需要上传文件
                $underwritingResponse->setError($underwritingResponse->getError() . " 请上传身份证，行驶证信息");
            }
            return $underwritingResponse;
        }

        return $underwritingResponse;
    }

    /**
     * 支付
     * @param PolicyPaymentVisitor $paymentVisitor
     * @return PolicyPaymentResponse
     */
    public function policyPayment(PolicyPaymentVisitor $paymentVisitor): PolicyPaymentResponse
    {
        $request = new PolicyPaymentRequest();
        $request->setVisitor($paymentVisitor);

        /*** @var PolicyPaymentResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 文件上传
     * @param UploadFileVisitor $uploadFileVisitor
     * @return Response
     */
    public function uploadFile(UploadFileVisitor $uploadFileVisitor): Response
    {
        return new Response(200);
    }

    /**
     * 投保单状态查询
     * @param ProposalStatusVisitor $proposalStatusVisitor
     * @return ProposalStatusResponse
     */
    public function proposalStatus(ProposalStatusVisitor $proposalStatusVisitor): ProposalStatusResponse
    {
        $request = new ProposalStatusRequest();
        $request->setVisitor($proposalStatusVisitor);

        /*** @var ProposalStatusResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 撤单接口
     * @param ProposalRecallVisitor $revokeVisitor
     * @return Response
     */
    public function proposalRecall(ProposalRecallVisitor $revokeVisitor): Response
    {
        $request = new ProposalRecallRequest();
        $request->setVisitor($revokeVisitor);

        /*** @var ProposalRecallResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 电子保单下载
     * @param EPolicyDownloadVisitor $EPolicyVisitor
     * @return Response
     */
    public function EPolicyDownload(EPolicyDownloadVisitor $EPolicyVisitor): Response
    {
        $request = new EPolicyDownloadRequest();
        $request->setVisitor($EPolicyVisitor);

        /*** @var EPolicyDownloadResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 核保撤回
     * @param UnderwritingRecallVisitor $recallVisitor
     * @return mixed|void
     */
    public function underwritingRecall(UnderwritingRecallVisitor $recallVisitor): Response
    {
        $request = new ProposalRecallRequest();
        $request->setVisitor($recallVisitor);

        /*** @var ProposalRecallResponse $response */
        $response = $this->execute($request);
        return $response;
    }

    /**
     * 保单详情
     * @param PolicyInfoVisitor $policyInfoVisitor
     * @return Response
     */
    public function policyInfo(PolicyInfoVisitor $policyInfoVisitor): Response
    {
        return new Response(200);
    }

    public function nonCarProductList(NonCarProductListVisitor $nonCarProductListVisitor): Response
    {
        $request = new NonCarProductListRequest();
        $route = $request->route;
        $request->setVisitor($nonCarProductListVisitor);
        $request->agreementCode = $this->agreementNo;
        /*** @var NonCarProductListResponse $response */
        $response = $this->execute($request);

        if (!$response->isSuccess()) {
            return $response;
        }

        $printerAll = $response->printer;

        $printerAll = array_combine(array_column($printerAll->productList, 'planCode'), $printerAll->productList);

        $request->hasE200 = false;
        $request->setRoute($route);

        $response = $this->execute($request);

        foreach ($response->printer->productList as $item) {

            if (!key_exists($item['planCode'], $printerAll)) {
                $printerAll[] = $item;
            }
        }

        usort($printerAll, function ($a, $b) {
            return $a['premium'] >= $b['premium'];
        });

        $response->printer->productList = array_values($printerAll);

        return $response;
    }

    public function nonCarInquiry(NonCarInquiryVisitor $nonCarInquiryVisitor): Response
    {
        return new Response(200);
    }

    public function nonCarUnderwriting(NonCarInquiryVisitor $inquiryPrinter): Response
    {
        return new Response(200);
    }

    /**
     * 获取恒邦token
     * @return mixed|string
     */
    public function getAuthorizationToken()
    {
        $token = new LIHITokenRequest();
        /**
         * @var CommonResponse $response
         */
        $response = $this->execute($token);
        return $response->getBody();

    }

    /**
     * 获取验车码
     * @param ValidateCarVisitor $validateCarVisitor
     * @return ValidateCarResponse
     */
    public function validateCarCode(ValidateCarVisitor $validateCarVisitor): ValidateCarResponse
    {
        /*** @var $response ValidateCarResponse */
        $response = $this->execute(new ValidateCarRequest());

        return $response;
    }

    /**
     * 新车备案
     * @return void
     */
    public function newVehicleRegistration(PremiumInquiryVisitor $premiumInquiryVisitor)
    {
    }
}
